#include "json_util.h"

#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cstring>

#include "string_match.h"
#include "util_tools.h"


char *readJsonFile(const char *filename)
{
    FILE * fp = fopen(filename, "r");

    if (fp == NULL) {
        return NULL;
    }

    fseek(fp, 0L, SEEK_END);
    size_t len = (size_t)ftell(fp);
    char *data = (char *)malloc(len+1);
    fseek(fp,0L,SEEK_SET);
    fread(data, len, 1, fp);
    fclose(fp);
    return data;
}
char *readFile(const char *filename)
{
    return readJsonFile(filename);
}

int saveJsonFile(cJSON *root, const char *filename)
{
    FILE * fp = fopen(filename, "w");

    if (fp) {
        char *sz = cJSON_Print(root);
        fwrite(sz, strlen(sz), 1, fp);
        free(sz);
        fclose(fp);
        return 1;
    }

    return 0;
}

bool saveFile(const char *data, const char *filename)
{
    FILE * fp = fopen(filename, "w");

    if (fp) {
        fwrite(data, strlen(data), 1, fp);
        fclose(fp);
        return true;
    }

    return false;
}

void freeData(char *data)
{
    if (data)
        free(data);
}

std::vector<std::string> parseStringObject(cJSON *js)
{
    std::vector<std::string> regs;

    if (!js)
        return regs;

    if (js->type == cJSON_Array) {
        int item_name = 0;
        regs.reserve(static_cast<size_t>(cJSON_GetArraySize(js)));
        do {
            cJSON *js_item = cJSON_GetArrayItem(js, item_name++);
            if (js_item && js_item->type == cJSON_String) {
                std::string str = js_item->valuestring;
                if(str.size() == 0)
                {
                    regs.clear();
                    return regs;
                }
                regs.push_back(js_item->valuestring);
            }
            else
                break;
        } while(true);
    }
    else if (js->type == cJSON_String) {
        std::string str = js->valuestring;
        std::string name;
        if (str.size() == 0)
        {
            return regs;
        }
        int index0, index1;
        if (splitRegNames(str, name, index0, index1)) {
            regs.reserve(static_cast<size_t>(index1-index0+1));
            for (int index=index0; index<=index1; index++) {
                regs.push_back(name + i32toa(index));
            }
        }
        else {
            regs.push_back(str);
        }
    }

    return regs;
}

std::vector<std::string> parseString(const std::string &str)
{
    std::vector<std::string> regs;

    std::string name;
    int index0, index1;
    if (splitRegNames(str, name, index0, index1)) {
        regs.reserve(static_cast<size_t>(index1-index0+1));
        for (int index=index0; index<=index1; index++) {
            regs.push_back(name + i32toa(index));
        }
    }
    else {
        regs.push_back(str);
    }

    return regs;
}
